package com.ss.android.image;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.widget.ImageView;

import com.bytedance.common.utility.Logger;
import com.facebook.drawee.view.SimpleDraweeView;
import com.squareup.picasso.BitmapDiskLruCache;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Request;
import com.squareup.picasso.RequestCreator;
import com.squareup.picasso.Utils;
import com.ss.android.article.browser.R;
import com.ss.android.image.a.a.TTDraweeControllerBuilderSupplier;

import java.io.File;

public final class FrescoUtils {
    private static boolean initialized = false;
    private static Context sContext;

    public static void init(Context context) {
        if (FrescoUtils.initialized) {
            Logger.d("FrescoUtils", "Fresco already init");
            return;
        }

        try {
            FrescoUtils.sContext = context;
            android.support.design.a.sContext = context;
            TTDraweeControllerBuilderSupplier ttDraweeControllerBuilderSupplier = new TTDraweeControllerBuilderSupplier(context);
            android.support.design.a.sTTDraweeControllerBuilderSupplier = ttDraweeControllerBuilderSupplier;
            SimpleDraweeView.initialize(ttDraweeControllerBuilderSupplier);
            Picasso.Builder picassoBuilder = new Picasso.Builder(context);
            File picassoCache = new File(
                    Environment.getExternalStorageDirectory().getPath() + "/Android/data/" + context.getPackageName() + "/cache/",
                    "picasso-cache");
            if (!picassoCache.exists()) {
                picassoCache.mkdirs();
            }

            BitmapDiskLruCache bitmapDiskLruCache = new BitmapDiskLruCache(picassoCache, FrescoUtils.getSpaceSize(picassoCache));
            if (picassoBuilder.bitmapDiskLruCache != null) {
                throw new IllegalStateException("Disk cache already set.");
            }

            picassoBuilder.bitmapDiskLruCache = bitmapDiskLruCache;
            Picasso.setSingleton(picassoBuilder.build());
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        FrescoUtils.initialized = true;
    }

    public static void preload(Uri uri, Context context) {
        Picasso.with(context).load(uri).into((Callback) null);
    }

    public static boolean isCached(Uri uri) {
        return uri != null
                && Picasso.with(FrescoUtils.sContext).cached(Picasso.with(FrescoUtils.sContext).load(uri).createRequest(System.nanoTime()));
    }

    public static void clearCache() {
        Picasso picasso = Picasso.with(sContext);
        if (picasso.bitmapDiskLruCache != null) {
            BitmapDiskLruCache bitmapDiskLruCache = picasso.bitmapDiskLruCache;
            if (bitmapDiskLruCache.diskLruCache != null) {
                bitmapDiskLruCache.diskLruCache.setMaxSize(0L);
            }
        }
    }

    public static Request[] buildImageRequests(Image image) {
        if (image == null) {
            return new Request[0];
        } else {
            Request[] requests;
            if (image.url_list != null && !image.url_list.isEmpty()) {
                requests = new Request[image.url_list.size()];
                for (int i = 0; i < image.url_list.size(); i++) {
                    requests[i] = Picasso.with(FrescoUtils.sContext)
                            .load(Uri.parse(((Image.UrlItem) image.url_list.get(i)).url))
                            .image(image)
                            .createRequest(System.nanoTime());

                }
                return requests;
            }
            requests = new Request[1];
            Picasso picasso = Picasso.with(FrescoUtils.sContext);
            String url = TextUtils.isEmpty(image.url) ? image.local_uri : image.url;
            requests[0] = picasso.load(Uri.parse(url)).image(image).createRequest(System.nanoTime());
            return requests;
        }
    }

    public static Request[] buildImageRequests(Image image, int width, int height) {
        if (image == null) {
            return new Request[0];
        } else {
            if (image.url_list != null && !image.url_list.isEmpty()) {
                Request[] requests = new Request[image.url_list.size()];
                for (int i = 0; i < image.url_list.size(); i++) {
                    requests[i] = Picasso.with(FrescoUtils.sContext)
                            .load(Uri.parse(((Image.UrlItem) image.url_list.get(i)).url))
                            .resize(width, height)
                            .image(image)
                            .createRequest(System.nanoTime());
                }
                return requests;
            } else {
                String url = TextUtils.isEmpty(image.url) ? image.local_uri : image.url;
                return new Request[]{Picasso.with(FrescoUtils.sContext).load(Uri.parse(url)).resize(width, height).image(image).createRequest(System.nanoTime())};
            }
        }
    }

    private static long getSpaceSize(File file) {
        long expectedSpaceSize;
        long defaultSpaceSize = 10 * 1024 * 1024L;
        try {
            StatFs statFs = new StatFs(file.getAbsolutePath());
            expectedSpaceSize = (long) statFs.getBlockSize() * (long) statFs.getBlockCount() / 50;
        } catch (IllegalArgumentException argumentException) {
            expectedSpaceSize = defaultSpaceSize;
        }

        return Math.max(Math.min(expectedSpaceSize, 100 * 1024 * 1024L), defaultSpaceSize);
    }

    public static void load(Context context, Uri uri, Callback callback) {
        Picasso.with(context).load(uri).into(callback);
    }

    @TargetApi(value = 11)
    @Deprecated
    public static void load(ImageView imageView, Uri uri, int placeholderResId, final ImageLoaderWithRetry imageLoaderWithRetry) {
        RequestCreator requestCreator = Picasso.with(FrescoUtils.sContext).load(uri);
        if (!requestCreator.hasPlaceholder) {
            throw new IllegalStateException("Already explicitly declared as no placeholder.");
        }

        if (placeholderResId == 0) {
            throw new IllegalArgumentException("Placeholder image resource invalid.");
        }

        requestCreator.placeholderResId = placeholderResId;
        requestCreator.into(imageView, new Callback() {
            public final void onSuccess(Drawable drawable, Picasso.LoadedFrom loadedFrom) {
                if (imageLoaderWithRetry != null) {
                    if (drawable == null && imageLoaderWithRetry.currentIndex < imageLoaderWithRetry.image.url_list.size() - 1) {
                        ++imageLoaderWithRetry.currentIndex;
                        imageLoaderWithRetry.load();
                    }
                }
            }

            public final void onError(Exception exception) {
            }
        });
    }

    @Deprecated
    public static void load(ImageView imageView, Image image) {
        new ImageLoaderWithRetry(imageView, image).load();
    }

    public static boolean isInitialized() {
        return FrescoUtils.initialized;
    }

    public static File tryGetCacheFile(Uri uri) {
        if (uri != null) {
            Picasso picasso = Picasso.with(FrescoUtils.sContext);
            if (picasso.bitmapDiskLruCache != null) {
                return picasso.bitmapDiskLruCache.getCacheFile(Utils.createKey(picasso.load(uri).createRequest(System.nanoTime())));
            }
        }
        return null;
    }

    public static final class ImageLoaderWithRetry {
        Image image;
        int currentIndex;
        private ImageView imageView;
        private int placeholderResId;

        ImageLoaderWithRetry(ImageView imageView, Image image) {
            this.imageView = imageView;
            this.image = image;
            this.placeholderResId = R.color.bg_place_holder;
            this.currentIndex = 0;
        }

        public final void load() {
            Uri uri;
            if (this.image.url_list == null || (this.image.url_list.isEmpty())) {
                String imageUrl = TextUtils.isEmpty(this.image.url) ? this.image.local_uri : this.image.url;
                uri = Uri.parse(imageUrl);
            } else {
                uri = Uri.parse(this.image.url_list.get(this.currentIndex).url);
            }
            FrescoUtils.load(this.imageView, uri, this.placeholderResId, this);
        }
    }
}

